假设要开发的整个系统会包含很多管理平台，比如发票管理平台、支付管理平台、大数据平台、包括用户管理平台。包括网上很多的权限管理系统、通用的低代码平台，都有一个特点，只关心了自己的权限。如果每次都要复制一套关于权限的配置，那就意味着每一个系统都要做一遍权限的处理，这个对于整体公司架构来说是不合理的，相当于做了很多的重复工作。

还有一个问题就是，好多系统不是自己开发的，可能原来就有，老系统做的权限很烂，存在越权问题；整个公司有多个项目，项目权限管理混乱，没有统一的权限认证中心。

这时候需要考虑的一个问题就是，老系统怎么集成？新系统怎么集成？

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/20241218142425.png"/>

这个时候，需要从底层来思考一下，什么叫做权限？权限究竟处理的是什么？

做一个通用的权限系统，是基于需求出发的，而不是为了学习一个 Spring Security 、Shiro 框架等。

那么权限在现实生活中是什么？ 这里举一个生活中的例子，比如我要进入一个体育场，会先看你有没有门票；如果是公司职员，能不能进入；体育场有很多门，有些门可能不需要票，而是其它方式，比如工作人员后门刷脸。在体育场这个例子中，所谓的权限就是指可不可以进入体育场。
<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/20241218144959.png"/>
这里会抽象出一些概念
* Principle： 唯一主体，要处理的是否有凭证的对象。
* Credentials（凭证），代表一个约定，一个密钥，凭证可以为 null。

对于某些情况，只认 Principle ，不需要 Credentials ；对于某些情况，只认 Credentials。


那么对于一个 web 系统，最关心的是什么呢？
如果权限系统想做一套通用的权限管理框架，那么需要知道，需要框架来帮我们做什么？就需要站在需求的角度去考虑了。

一个 Web 系统，里面有很多 URL，希望针对这些 URL，给它们一个唯一的编码，这在 Spring Security 中叫做安全对象。

一个安全对象在系统里面是唯一的。如果我能访问它，就意味着有一个授权码或一个资源。

在系统中，一个 URL 就是一个资源，那么自然就可以配置，某个资源谁可以访问，即谁拥有这个编码，谁就可以。类似体育场的座位（票号写着 13 号，就可以坐 13 号），对于 URL 也是。

另外，还需要考虑如何让系统使用起来更加简单，对于系统来说，编码是权限系统的事情。编码由权限系统提供， 其它系统希望得到的期望是访问 URL 的时候，将用户和权限码的对应关系给到它。
只要把对应关系给其它系统，其它系统在访问之前能拿到用户所拥有的权限，就可以自己控制这个资源可不可以访问了，这就一个应用系统对于权限的需求。

应用系统希望，权限像插件一样放在应用之上，在权限系统中配置了资源之后，当用户访问系统的时候，把用户和权限的对应关系给我。只要我能够获得这种关系，我自己就能决定能否可以访问。

这种关系可以需要放到一个所谓的上下文中，还应该包括一些额外信息，上下文中应当有的信息包括：
* 用户和权限的对应关系
* 查询到关于用户的额外信息，还需要关心某些用户有没有特权或者限制，比如管理员。

Context 从 starter 中获取，
然后将用户与权限的关系；用户额外信息放进去。
将来在访问中就可以灵活控制了。

上面就是权限需求，任何系统的权限都只有上面这些。

那些 URL 不做权限控制，那些 URL 做控制，这些需要应用自己去配置。

而用户与权限的对应关系、用户额外信息，需要到其它系统中去查询，这里是属于一个变化的点（提供一个接口），不关系是否是新老系统，新老系统可以去任何地方查询，这样对于应用来说就足够灵活了。

通过接口查询到之后，权限系统会将其放入 Context 中。

这样在任何的 URL 访问时，都可以通过 Context 拿到相应的信息，这时候就解决了所有系统的权限问题。

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/20241218152726.png"/>


在系统中，要先考虑授权问题，再考虑登录问题，上面说的是所有用户登录之后的授权问题，登录是有 SSO 。

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/20241218163413.png"/>

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/20241218165144.png"/>

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/20241218165308.png"/>

## 权限之认证
:::tip
框架问题解决的是生活中问题，生活中权限是怎么做的，框架就应该怎么做。
:::
还是以体育场场景为例，登录的时候有两个很重要的概念，就是 Principle 和 Credentials 。

权限领域主要是解决两大问题
1. Authentication 认证
2. Authorization 授权

权限系统是一个三方应用，通过插件解决了授权问题，根据 token 获取用户和权限的对应关系。还有一个问题对应的是 登录，即认证问题 Authentication 。


继续往下抽象，门票、刷脸、指纹、管理员（内部人员）这些在框架里统一抽象为认证对象，可以是 Principle ，也可以是 Credentials。描述了 Authentication。可以继续抽象为 Token 。是 Authentication 认证的具化，代表了某个不同的认证方式。

所有的 Authentication 都可以抽象为一个令牌。

各种各样场景的登录，都可能会对应不同的入口，在程序中对应多个 Filter。

有了 Filter， 还需要有人检票，在程序中叫做 Provider 认证处理。


认证通过之后，能不能让你进入，还涉及到一个概念 AccessManager，继续抽象，得到 Voter。


怎么投票？ 多数通过或者别的控制逻辑，这个概念在程序中的体现是Controller 上的 @Securied、@PreAuth 等注解。


输入密码、刷脸等方式，认证通过之后，会得到一个 Token，这时会发现， token 是进入系统的另外一种方式。理论上，还是一种认证方式。

所以还是需要 Token 的 Filter 、Token 的 Provider，通过认证之后给予授权。
<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/20241218175705.png"/>

Auth2 也是一种类似 Token 的认证方式。

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/20241218182721.png"/>

## Spring Security 的源码









